using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;


namespace homeworkhero
{
    /// <summary>
    /// This is a game component that implements IUpdateable.
    /// </summary>
    public class CollisionManager : Microsoft.Xna.Framework.GameComponent
    {
        public CollisionManager(Game game)
            : base(game)
        {
            // TODO: Construct any child components here
        }

        /// <summary>
        /// Allows the game component to perform any initialization it needs to before starting
        /// to run.  This is where it can query for any required services and load content.
        /// </summary>
        public override void Initialize()
        {
            // TODO: Add your initialization code here

            base.Initialize();
        }

        public void checkCollisions(LinkedList<Player> players, LinkedList<CollidableSprite> list)
        {
            /* handle player-sprite collisions */
            LinkedList<Player>.Enumerator e1 = players.GetEnumerator();
            LinkedList<CollidableSprite>.Enumerator e2;
            while(e1.MoveNext()) {
                Player thePlayer = e1.Current;
                if(!thePlayer.shouldCollide())
                    continue;

                e2 = list.GetEnumerator();
                while(e2.MoveNext()) {
                    CollidableSprite theSprite = e2.Current;

                    if(thePlayer == theSprite || thePlayer.Equals(theSprite))
                        continue;

                    if (!theSprite.shouldCollide())
                        continue;

                    if(thePlayer.getBounds().Contains(theSprite.getBounds()) != ContainmentType.Disjoint) {
                        handlePlayerSpriteCollision(thePlayer, theSprite);
                    }
                }
            }

            /* handle sprite-sprite collisions */
            LinkedList<CollidableSprite>.Enumerator e3;
            e2 = list.GetEnumerator();
            while(e2.MoveNext()) {
                CollidableSprite sprite1 = e2.Current;
                if(sprite1.getType() == CollidableSprite.CollidableSpriteType.PLAYER)
                    continue;
                if(!sprite1.shouldCollide())
                    continue;

                e3 = list.GetEnumerator();
                while(e3.MoveNext()) {
                    CollidableSprite sprite2 = e3.Current;

                    if(!sprite2.shouldCollide())
                        continue;

                    if(sprite1.getBounds().Contains(sprite2.getBounds()) != ContainmentType.Disjoint) {
                            handleSpriteSpriteCollision(sprite1, sprite2);
                    }
                }
            }
        }

        private void handlePlayerSpriteCollision(Player player, CollidableSprite sprite) {
            /* don't handle player-player; no friendly fire/collision */

            if (sprite.getType() == CollidableSprite.CollidableSpriteType.ENEMY)
            {
                sprite.damage(player.getDamage());
            }
            else if (sprite.getType() == CollidableSprite.CollidableSpriteType.PROP)
            {
                player.move(-player.getVelocity().X, -player.getVelocity().Y);
                player.setVelocity(Vector2.Zero);
            }
            /* don't handle bullet; these are fired by the player(s) */
        }

        private void handleSpriteSpriteCollision(CollidableSprite sprite1, CollidableSprite sprite2) {
            if(sprite1.getType() == CollidableSprite.CollidableSpriteType.PLAYER) {
                /* do nothing */
            }
            else if (sprite1.getType() == CollidableSprite.CollidableSpriteType.ENEMY)
            {
                if (sprite2.getType() == CollidableSprite.CollidableSpriteType.PLAYER)
                {
                    sprite2.damage(sprite1.getDamage());
                    ((Player)sprite2).hit();
                }
                else if (sprite2.getType() == CollidableSprite.CollidableSpriteType.BULLET)
                {
                    /* handled with bullet-enemy */
                }
                else if (sprite2.getType() == CollidableSprite.CollidableSpriteType.PROP)
                {
                    /* the AI should avoid this */
                }
            }
            else if (sprite1.getType() == CollidableSprite.CollidableSpriteType.BULLET)
            {
                if (sprite2.getType() == CollidableSprite.CollidableSpriteType.ENEMY)
                {
                    sprite2.damage(sprite1.getDamage());
                    sprite1.destroy();
                }
                else if (sprite2.getType() == CollidableSprite.CollidableSpriteType.PROP)
                {
                    sprite1.destroy();
                }
            }
            else if (sprite1.getType() == CollidableSprite.CollidableSpriteType.PROP)
            {
                /* props don't collide into things; things collide into prop */
            }

        }
    }
}